#include "Wt.h"

/* Get the session associated with an interp */

WtSession *WtGetAssocSession(Tcl_Interp *interp)
{
  WtContext *w = WtGetAssocContext(interp);
  return w && w->active ? &w->active->session : NULL;
}


/* Session command */

int WtSessionCmd(ClientData clientData, Tcl_Interp *interp,
                 int objc, Tcl_Obj *const objv[])
{
  int ret = TCL_ERROR, execHandler = 1, cmdObjc, i;
  char *subCmd;
  WtContext *w = WtGetAssocContext(interp);
  WtSession *session = WtGetAssocSession(interp);
  Tcl_Obj *cmdObjv;

  if (objc >= 2) {

    subCmd = Tcl_GetString(objv[1]);

    if (!strcmp(subCmd, "handler")) {

      /* handler command */

      if (objc != 2 && objc != 3) {
        Tcl_AppendResult(interp, "Incorrect usage. Should be: ",
        WtToString(objv[0]), " ", WtToString(objv[1]), " ?handler?");
      } else if (objc == 2) {
        Tcl_SetObjResult(interp, session->handler);
        execHandler = 0;
        ret = TCL_OK;
      } else if (objc == 3) {
        Tcl_DecrRefCount(interp, session->handler);
        session->handler = objv[2];
        Tcl_IncrRefCount(interp, session->handler);
        Tcl_SetObjResult(interp, session->handler);
        execHandler = 0;
        ret = TCL_OK;
      }
    }
  }

  if (execHandler) {
    if (!Tcl_GetCharLength(session->handler)) {
      Tcl_AppendResult(interp, "No session handler installed. ",
        "Please define a session handler before using the session command.");
    } else {
      cmdObjc = objc;
      cmdObjv = ckalloc(cmdObjc * sizeof(Tcl_Obj *));
      assert(cmdObjv);
      cmdObjv[0] = WtNewString(session->handler);
      Tcl_IncrRefCount(cmdObjv[0]);
      for (i = 1; i <= objc; ++i) {
        cmdObjv[i] = objv[i];
        Tcl_IncrRefCount(cmdObjv[i]);
      }
      ret = Tcl_EvalObjv(interp, cmdObjc, cmdObjv,  TCL_EVAL_DIRECT);
      for (i = 0; i <= cmdObjc; ++i) {
        Tcl_DecrRefCount(cmdObjv[i]);
      }
    }
  }

  return ret;
}
